package org.client.chat;

import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.Socket;

import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.widgets.Display;
import org.model.ChatStrings;
import org.model.Friend;
import org.secure.SecureInputStream;
import org.secure.SecureOutputStream;

import sun.audio.AudioPlayer;

public class ITalkClient extends ITalkChatWindow implements DisposeListener{

	
	private String loginName;
	private Friend mFriend;
	private byte[] key;
	private Socket clientSocket;
	private SecureOutputStream outputStream;
	private SecureInputStream inputStream;
	boolean isSending = false;

	public ITalkClient(Friend friend, String loginName, byte[] key)
	{
		//super(friend.getName());
		System.out.println("After super");
		this.loginName = loginName;
		mFriend = new Friend(friend.getName(),friend.getAddress());		
		this.key = key;
		shell.setText(friend.getName());
		shell.addDisposeListener(this);
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}
		
		
	}
	
	private class ChatListener extends Thread
	{
		private SecureInputStream inputStream;
		private String line;
		public ChatListener(SecureInputStream is)
		{
			inputStream =is;
		}
		@Override
		public void run() {
			System.out.println("Thread is started");
			try {
				while(true)
				{
					
					line = inputStream.readLine();
					if(checkIfEndChat(line))
						break;
					ITalkClient.this.display.asyncExec(new Runnable(){
						@Override
						public void run() {
							if(isSending)
							{
								chatWindow.append(mFriend.getName()+ChatStrings.USER_NEXT+line+"\n");
								isSending = false;
							}else
								chatWindow.append(ChatStrings.SAPCES+line+"\n");		
							if(line.toLowerCase().compareTo("buzz") == 0)
							{
								vibrate();
								AudioPlayer.player.start(getBuzzAudioStream());
								return;
							}
							AudioPlayer.player.start(getMessageAudioStream());
						}});
				}
			} catch (Exception e) {
				System.out.println("you parnter has closed chating");
				try {
					Display.getDefault().asyncExec(new Runnable(){
						@Override
						public void run() {
							chatWindow.append(ChatStrings.END_CHAT);		
						}});	
				} catch (Exception e2) {
					e2.printStackTrace();
				}
				
				
				//e.printStackTrace();
			}
		}
	}
	@Override
	protected void handleSend(String line) {
		try {
			if(clientSocket == null)
			{
				//System.out.println(mFriend.getName());
				InetAddress address = InetAddress.getByAddress(mFriend.getAddress().getIpAddress());
				clientSocket = new Socket(address,mFriend.getAddress().getPort());
				outputStream = new SecureOutputStream(clientSocket.getOutputStream());
				inputStream = new SecureInputStream(new InputStreamReader(clientSocket.getInputStream()));
				outputStream.setPrivateKey(key);
				inputStream.setPrivateKey(key);
				outputStream.writeString(loginName+ChatStrings.END_LINE);
				outputStream.setClient(true);
				inputStream.setClient(true);
				new ChatListener(inputStream).start();
				//display.asyncExec(new ChatListener(inputStream));
			}
			
			if(line == null || line.compareTo("") == 0)
				return;
			if(!isSending)
			{
				chatWindow.append(loginName+ChatStrings.USER_NEXT+line+"\n");
				isSending = true;
			}
			else
				chatWindow.append(ChatStrings.SAPCES+line+"\n");
			
			//chatArea.setCaretPosition(chatArea.getText().length());
			outputStream.writeString(line+ChatStrings.END_LINE);	
		} catch (Exception e) {
			//System.err.print("partner is closed");
			e.printStackTrace();
		}
		
	}
	@Override
	public void widgetDisposed(DisposeEvent e) {
		//System.out.println("i am killed");
		try {
			if(clientSocket != null)
			{
				byte[] end = new byte[3];
				end[0] = 1;
				end[1] = 2;
				end[2] = 3;
				String bytes = new String(end);
				outputStream.writeString(bytes+ChatStrings.END_LINE);
				clientSocket.close();
			}
		} catch (Exception e2) {
			e2.printStackTrace();
		}
		
	}

}
